package club.emergency.wechat.department_staff.search.provider.impl;

import club.emergency.wechat.common.response.ResponseEntity;
import club.emergency.wechat.common.response.StatusCode;
import club.emergency.wechat.department_staff.search.DepartmentStaffSearch;
import club.emergency.wechat.exeception.provider.ProviderException;
import club.emergency.wechat.model.staff.DepartmentStaff;
import club.emergency.wechat.persistence.staff.DepartmentStaffMapper;
import club.emergency.wechat.redis.RedisOperation;
import club.emergency.wechat.redis.common.RedisKeyConstant;
import club.emergency.wechat.sso.jwt.JwtTokenUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * Create with IntelliJ IDEA
 * Project Name: wechat
 * Package Name: club.emergency.wechat.department_staff.search.provider.impl
 * Date: 2019/4/2
 *
 * @author: 快乐的小菌菌
 * Description:
 */
@RestController
public class DepartmentStaffSearchImpl implements DepartmentStaffSearch {

    private DepartmentStaffMapper departmentStaffMapper;

    private RedisOperation<DepartmentStaff> redisOperation;

    @Value("${jwt.secretKey}")
    private String secretKey;

    @Value("${jwt.accessTokenExpired}")
    private long accessTokenExpired;

    @Value("${jwt.refreshTokenExpired}")
    private long refreshTokenExpired;

    public DepartmentStaffSearchImpl(DepartmentStaffMapper departmentStaffMapper, RedisOperation<DepartmentStaff> redisOperation) {
        this.departmentStaffMapper = departmentStaffMapper;
        this.redisOperation = redisOperation;
    }

    @Override
    public String flipList(
            @RequestParam(value = "departmentId", required = false) Long departmentId,
            @RequestParam(value = "departmentCode", required = false) String departmentCode,
            @RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
            @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize
    ) {
        Page<DepartmentStaff> page = new Page<>(pageNo, pageSize);
        QueryWrapper<DepartmentStaff> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Objects.nonNull(departmentId), "department_id", departmentId);
        queryWrapper.likeRight(Objects.nonNull(departmentCode), "department_code", departmentCode);
        return ResponseEntity.ok(StatusCode.DB_SEARCH_OK, "查询企业人员接口成功！", departmentStaffMapper.selectPage(page, queryWrapper));
    }

    @Override
    public String signature(String openId) {
        DepartmentStaff departmentStaff;
        try {
            departmentStaff = getStaffByOpenId(openId);
        } catch (ProviderException e) {
            return ResponseEntity.ok(StatusCode.LOGIN_ERROR, e.getMessage());
        }
        TokenModel tokenModel = createToken(departmentStaff.getId());
        tokenModel.setDepartmentStaff(departmentStaff);
        return ResponseEntity.ok(StatusCode.LOGIN_OK, "获取签名成功！", tokenModel);
    }

    @Override
    public String updateToken() {
        return ResponseEntity.ok(StatusCode.AUTHORIZATION_UPDATE_OK, "Token更新成功！", createToken(null));
    }

    /**
     * 根据OpenId获取Staff对象
     *
     * @param openId 微信openid
     * @return 以字符串形式返回
     */
    private DepartmentStaff getStaffByOpenId(String openId) {
        Boolean flag = redisOperation.hasKey(openId);
        DepartmentStaff departmentStaff;
        if (flag) {
            departmentStaff = redisOperation.get(RedisKeyConstant.STAFF_OPENID + openId, DepartmentStaff.class);
        } else {
            QueryWrapper<DepartmentStaff> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("open_id", openId);
            DepartmentStaff departmentStaffForQuery = departmentStaffMapper.selectOne(queryWrapper);
            //如果staff为null，证明该用户还未注册。
            if (Objects.isNull(departmentStaffForQuery)) {
                throw new ProviderException("没有OpenId对应的用户，请企业用户先注册绑定之后再进行操作!");
            } else {
                departmentStaff = departmentStaffForQuery;
                redisOperation.add(RedisKeyConstant.STAFF_OPENID + openId, departmentStaff, 3, TimeUnit.HOURS);
            }
        }
        return departmentStaff;
    }

    private TokenModel createToken(Long id) {
        String accessToken = JwtTokenUtil.createJWT(secretKey, String.valueOf(id), "accessToken", accessTokenExpired);
        String refreshToken = JwtTokenUtil.createJWT(secretKey, String.valueOf(id), "refreshToken", refreshTokenExpired);
        return new TokenModel(accessToken, refreshToken, null);
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private class TokenModel {
        private String accessToken;
        private String refreshToken;
        private DepartmentStaff departmentStaff;
    }
}
